import os
import json
import matplotlib.pyplot as plt
from matplotlib.path import Path
import networkx as nx

# 设置默认流程字典
default_workflow_dict = {
    "导弹突防裁决规则": [
        "《导弹突防裁决表》",
        "输入<导弹型号>",
        "输入<导弹数量>",
        "输入<反导型号>",
        "输入<修正值>",
        "点击<多发裁决>"
    ],
    "导弹毁伤裁决规则": [
        "《导弹毁伤裁决表》",
        "输入<导弹型号>",
        "输入<导弹数量>",
        "输入<修正值>",
        "点击<多发裁决>"
    ],
    "地面作战裁决规则": [
        "《地面作战裁决表》",
        "输入<兵力比>",
        "<装备优势>修正",
        "<地形优势>修正",
        "<疲劳等级>修正",
        "<生成随机数>"
    ]
}

# 画图设置
plt.rcParams["font.family"] = ["SimHei", "Microsoft YaHei", "sans-serif"]
plt.rcParams['axes.unicode_minus'] = False  
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']

class Workflow:

    def __init__(self):
        self.dict = self.load_workflow_dict()
        self.fig, self.ax = plt.subplots(figsize=(2, 4), dpi=130, facecolor='none')  # 创建matplotlib图表

        # self.fig.set_facecolor('#004040')  # 设置图形背景为浅蓝色

        self.current_workflow = list(self.dict.keys())[0]  # 当前流程
        self.current_step = 0  # 当前步骤
        self.step_descriptions = self.dict[self.current_workflow] 
        self.total_steps = len(self.step_descriptions)
        
    # 从本地文件加载流程字典
    def load_workflow_dict(self, filepath='data/workflow_dict.json'):
        # workflow_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)
        if os.path.exists(filepath):
            try:
                with open(filepath, 'r', encoding='utf-8') as f:
                    loaded_dict = json.load(f)
                    if isinstance(loaded_dict, dict):
                        return loaded_dict
            except (json.JSONDecodeError, FileNotFoundError, PermissionError) as e:
                print(f"加载流程字典时出错: {str(e)}")
        else:
            print("流程字典文件不存在")
            return default_workflow_dict

    # 保存流程字典到本地文件
    def save_workflow_dict(self, filepath='data/workflow_dict.json'):
        try:
            with open(filepath, 'w', encoding='utf-8') as f:
                json.dump(self.dict, f, ensure_ascii=False, indent=4)
            return True
        except (FileNotFoundError, PermissionError) as e:
            print(f"保存流程字典时出错: {str(e)}")
            return False
        
    def plot_workflow(self, current_workflow=None, current_step=None):
        
        self.update(current_workflow, current_step)

        self.ax.clear()  # 清除当前图表
        
        G = nx.DiGraph()  # 创建有向图
        
        # 添加节点
        for i, step in enumerate(self.step_descriptions):
            # 当前步骤使用不同颜色
            color = "#6EDCFE" if i == self.current_step else "white"
            G.add_node(i, label=f"{i+1}. {step}", color=color)
        
        # 添加边
        for i in range(len(self.step_descriptions) - 1):
            G.add_edge(i, i+1)
        
        G = nx.DiGraph()  # 创建有向图

        # 添加节点
        for i, step in enumerate(self.step_descriptions):
            # 当前步骤使用不同颜色
            color = "#6EDCFE" if i == self.current_step else "white"
            G.add_node(i, label=f"{i+1}. {step}", color=color)
        
        # 添加边
        for i in range(len(self.step_descriptions) - 1):
            G.add_edge(i, i+1)

        pos = {i: (0, -i) for i in G.nodes}  # 设置节点竖直排列位置
        
        # 绘制节点（使用长方形）
        colors = [G.nodes[i]['color'] for i in G.nodes]
        verts = [(-5,-1), (5,-1), (5,1), (-5,1), (-5,-1)]  
        codes = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]
        node_size = 8000
        path = Path(verts, codes)
        nx.draw_networkx_nodes(G, pos, node_size=node_size, node_color=colors, edgecolors="black", ax=self.ax, node_shape=path)
        
        # 绘制边 - 调整箭头位置，使其紧挨着节点
        nx.draw_networkx_edges(G, pos, arrowstyle="->", arrowsize=10, ax=self.ax)
        
        # 绘制标签
        labels = {i: G.nodes[i]['label'] for i in G.nodes}
        nx.draw_networkx_labels(G, pos, labels, font_family='simhei', font_size=8, ax=self.ax)
        
        # 设置图表范围，固定宽度
        y_min = min(pos[i][1] for i in pos) - 1
        y_max = max(pos[i][1] for i in pos) + 1
        self.ax.set_ylim(y_min, y_max)
        self.ax.set_xlim(-1.5, 1.5)  # 固定宽度
        
        # 关闭坐标轴
        self.ax.axis('off')
        
        # 调整布局
        self.fig.tight_layout()

    def update(self, current_workflow=None, current_step=None):
        if current_workflow is not None:
            self.current_workflow = current_workflow
            self.step_descriptions = self.dict[self.current_workflow]
            self.total_steps = len(self.step_descriptions)
        if current_step is not None:
            self.current_step = current_step
       
if __name__ == '__main__':
    workflow = Workflow()
    workflow.plot_workflow()
    plt.show()